package com.yanfan.zutai.service.impl;

import com.yanfan.common.core.domain.AjaxResult;
import com.yanfan.common.core.domain.entity.SysDept;
import com.yanfan.common.core.domain.entity.SysUser;
import com.yanfan.common.utils.DateUtils;
import com.yanfan.common.utils.SecurityUtils;
import com.yanfan.common.utils.StringUtils;
import com.yanfan.system.mapper.SysDeptMapper;
import com.yanfan.system.service.ISysUserService;
import com.yanfan.zutai.domain.BDeviceZt;
import com.yanfan.zutai.domain.BDeviceZtUser;
import com.yanfan.zutai.domain.vo.ZutaiDataVo;
import com.yanfan.zutai.domain.vo.ZutaiVo;
import com.yanfan.zutai.mapper.BDeviceZtMapper;
import com.yanfan.zutai.mapper.BDeviceZtUserMapper;
import com.yanfan.zutai.service.IBDeviceZtUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.yanfan.common.utils.SecurityUtils.getLoginUser;

/**
 * 组态用户Service业务层处理
 *
 * @author kerwincui
 * @date 2024-02-02
 */
@Service
public class BDeviceZtUserServiceImpl implements IBDeviceZtUserService {
    @Resource
    private BDeviceZtUserMapper bDeviceZtUserMapper;
    @Resource
    private BDeviceZtMapper bDeviceZtMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private ISysUserService userService;

    /**
     * 查询组态用户
     *
     * @param ztId 组态用户主键
     * @return 组态用户
     */
    @Override
    public BDeviceZtUser selectBDeviceZtUserByZtId(Long ztId) {
        return bDeviceZtUserMapper.selectBDeviceZtUserByZtId(ztId);
    }

    /**
     * 查询组态用户列表
     *
     * @param bDeviceZtUser 组态用户
     * @return 组态用户
     */
    @Override
    public List<BDeviceZtUser> selectBDeviceZtUserList(BDeviceZtUser bDeviceZtUser) {
        return bDeviceZtUserMapper.selectBDeviceZtUserList(bDeviceZtUser);
    }

    /**
     * 新增组态用户
     *
     * @param bDeviceZtUser 组态用户
     * @return 结果
     */
    @Override
    public int insertBDeviceZtUser(BDeviceZtUser bDeviceZtUser) {
        List<BDeviceZtUser> deviceUsers = selectBDeviceZtUserList(bDeviceZtUser);
        if (!deviceUsers.isEmpty()) {
            throw new RuntimeException("该用户已添加, 禁止重复添加");
        }
        bDeviceZtUser.setCreateTime(DateUtils.getNowDate());
        bDeviceZtUser.setIsOwner(0L);
        SysUser sysUser = getLoginUser().getUser();
        bDeviceZtUser.setTenantId(sysUser.getDeptId());
        bDeviceZtUser.setTenantName(sysUser.getUserName());
        return bDeviceZtUserMapper.insertBDeviceZtUser(bDeviceZtUser);
    }

    /**
     * 修改组态用户
     *
     * @param bDeviceZtUser 组态用户
     * @return 结果
     */
    @Override
    public int updateBDeviceZtUser(BDeviceZtUser bDeviceZtUser) {
        bDeviceZtUser.setUpdateTime(DateUtils.getNowDate());
        return bDeviceZtUserMapper.updateBDeviceZtUser(bDeviceZtUser);
    }

    /**
     * 批量删除组态用户
     *
     * @param ztIds 需要删除的组态用户主键
     * @return 结果
     */
    @Override
    public int deleteBDeviceZtUserByZtIds(Long[] ztIds) {
        return bDeviceZtUserMapper.deleteBDeviceZtUserByZtIds(ztIds);
    }

    /**
     * 删除组态用户信息
     *
     * @param ztId 组态用户主键
     * @return 结果
     */
    @Override
    public int deleteBDeviceZtUserByZtId(Long ztId) {
        return bDeviceZtUserMapper.deleteBDeviceZtUserByZtId(ztId);
    }

    @Override
    public int insertBDeviceZtUserList(List<BDeviceZtUser> bDeviceZtUser) {
        try {
            bDeviceZtUser.forEach(deviceUser -> {
                deviceUser.setCreateTime(DateUtils.getNowDate());
                deviceUser.setIsOwner(0L);
                SysUser sysUser = getLoginUser().getUser();
                deviceUser.setTenantId(sysUser.getUserId());
                deviceUser.setTenantName(sysUser.getUserName());
            });
            return bDeviceZtUserMapper.insertBDeviceZtUserList(bDeviceZtUser);
        } catch (DuplicateKeyException e) {
            throw new RuntimeException("存在设备已经与用户绑定");
        }
    }

    @Override
    public SysUser selectShareUser(BDeviceZtUser user) {
        return bDeviceZtUserMapper.selectShareUser(user);
    }

    @Override
    public int deleteBDeviceZtUser(BDeviceZtUser bDeviceZtUser) {
        return bDeviceZtUserMapper.deleteBDeviceZtUser(bDeviceZtUser);
    }

    @Override
    public AjaxResult fpBDeviceZtUser(Long deptId, String zutaiId) {
        SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
        if (null == sysDept || null == sysDept.getDeptUserId()) {
            return AjaxResult.error("机构不存在或未绑定管理员，请调整后重试！");
        }
        Long deptUserId = sysDept.getDeptUserId();
        SysUser sysUser = userService.selectUserById(deptUserId);
        if (null == sysUser) {
            return AjaxResult.error("机构管理员不存在");
        }
        List<String> zutaiIdList = StringUtils.str2List(zutaiId, ",", true, true);
        // 使用 Stream API 将字符串列表转换为长整型列表
        List<Long> zutaiIdLongList = zutaiIdList.stream().map(Long::parseLong)  // 将每个字符串转换为 long 类型
                                                .collect(Collectors.toList());  // 收集结果到列表
        int flag = bDeviceZtUserMapper.updateBDeviceZtUserlist(deptId, sysUser.getUserName(), zutaiIdLongList);
        return flag > 0 ? AjaxResult.success("分配组态成功") : AjaxResult.error("分配组态失败");
    }

    @Override
    public AjaxResult insertfpUser(Long deptId, String dictcode) {
        SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
        if (null == sysDept || null == sysDept.getDeptUserId()) {
            return AjaxResult.error("机构不存在或未绑定管理员，请调整后重试！");
        }
        Long deptUserId = sysDept.getDeptUserId();
        SysUser sysUser = userService.selectUserById(deptUserId);
        if (null == sysUser) {
            return AjaxResult.error("机构管理员不存在");
        }
        List<String> dictIdList = StringUtils.str2List(dictcode, ",", true, true);
        // 使用 Stream API 将字符串列表转换为长整型列表
        List<Long> dictIdLongList = dictIdList.stream().map(Long::parseLong)  // 将每个字符串转换为 long 类型
                .collect(Collectors.toList());  // 收集结果到列表
        int flag = bDeviceZtUserMapper.updatefpUserList(deptId, dictIdLongList);
        return flag > 0 ? AjaxResult.success("分配图库成功") : AjaxResult.error("分配图库失败");
    }

    @Override
    public List<ZutaiVo> zutaiList() {
        Long deptId = SecurityUtils.getDeptId();
        return bDeviceZtUserMapper.zutaiList(deptId);
    }

    @Override
    public AjaxResult bDeviceZtList(ZutaiDataVo zutaiDataVo) {
        AjaxResult ajaxResult = new AjaxResult();
        Long deptId = SecurityUtils.getDeptId();
//        Long deptId = 100L;
        zutaiDataVo.setDeptId(deptId);
        List<BDeviceZt> bDeviceZts = bDeviceZtUserMapper.bDeviceZtList(zutaiDataVo);

        if(zutaiDataVo.getDateType().equals("1")){
            // 按照小时分组并统计每个小时的数量
            Map<Integer, Long> hourCountMap = bDeviceZts.stream()
                    .collect(Collectors.groupingBy(
                            item -> item.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().getHour(),
                            Collectors.counting()
                    ));
            // 填充Map，确保每个小时都有一个初始值0
            for (int i = 0; i < 24; i++) {
                hourCountMap.put(i, 0L);
            }
            // 使用stream来计算每个小时的出现次数
            hourCountMap.replaceAll((key, value) -> value + bDeviceZts.stream()
                    .filter(item -> ZonedDateTime.ofInstant(item.getCreateTime().toInstant(), ZoneId.systemDefault())
                            .getHour() == key)
                    .count());
            // 创建两个列表，一个用于存储小时，一个用于存储数据
            List<String> hours = new ArrayList<>();
            List<Long> counts = new ArrayList<>();

            IntStream.range(0, 24).forEach(hour -> {
                hours.add(hour+"时");
                counts.add(hourCountMap.getOrDefault(hour, 0L)); // 使用getOrDefault以确保没有数据的小时计数为0
            });
            ajaxResult.put("hours", hours);
            ajaxResult.put("counts", counts);
            return ajaxResult;
        }
        else if(zutaiDataVo.getDateType().equals("2")){
            // 按照日分组并统计每天的数量
            Map<LocalDate, Long> dayCountMap = bDeviceZts.stream()
                    .collect(Collectors.groupingBy(
                            item -> item.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
                            Collectors.counting()
                    ));
            // 填充Map，确保每一天都有一个初始值0
            LocalDate startDate = LocalDate.parse(zutaiDataVo.getStartDate());
            for (int i = 0; i <= 30; i++) {
                LocalDate date = startDate.plusDays(i);
                dayCountMap.putIfAbsent(date, 0L);
            }
            // 创建两个列表，一个用于存储日期，一个用于存储数据
            List<String> dates = new ArrayList<>();
            List<Long> counts = new ArrayList<>();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d");
            IntStream.range(0, 31).forEach(day -> {
                LocalDate date = startDate.plusDays(day);
                String formattedDate = date.format(formatter); // 使用DateTimeFormatter格式化日期
                dates.add(formattedDate+"日");
                counts.add(dayCountMap.getOrDefault(date, 0L)); // 使用getOrDefault以确保没有数据的日期计数为0
            });
            ajaxResult.put("hours", dates);
            ajaxResult.put("counts", counts);
            return ajaxResult;
        }
        else if(zutaiDataVo.getDateType().equals("3")){
            // 按照月分组并统计每个月的数量
            Map<YearMonth, Long> monthCountMap = bDeviceZts.stream()
                    .collect(Collectors.groupingBy(
                            item -> YearMonth.from(item.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()),
                            Collectors.counting()
                    ));
            // 填充Map，确保每个月都有一个初始值0
            YearMonth thisYear = YearMonth.of(YearMonth.now().getYear(), 1);
            for (int i = 0; i < 12; i++) {
                YearMonth yearMonth = thisYear.plusMonths(i);
                monthCountMap.putIfAbsent(yearMonth, 0L);
            }
            // 创建两个列表，一个用于存储月份，一个用于存储数据
            List<String> months = new ArrayList<>();
            List<Long> counts = new ArrayList<>();

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM"); // 格式化月份，确保两位数
            IntStream.range(0, 12).forEach(month -> {
                YearMonth yearMonth = thisYear.plusMonths(month);
                String formattedDate = yearMonth.format(formatter); // 使用DateTimeFormatter格式化月份
                months.add(formattedDate+"月");
                counts.add(monthCountMap.getOrDefault(yearMonth, 0L)); // 使用getOrDefault以确保没有数据的月份计数为0
            });
            ajaxResult.put("hours", months);
            ajaxResult.put("counts", counts);
            return ajaxResult;
        }
        return ajaxResult;
    }
}

